﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Web;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Utility.Json;
using Hxj.Data;
using System.Reflection;

namespace Utility
{
    /// <summary>
    /// 类型转换帮助类
    /// </summary>
    public static class ConvertHelper
    {
        public static DateTime GetNowDateTime()
        {
            return DateTime.Now;
        }


        #region ========List集合转换为DataTable========
        /// <summary>
        /// 转化一个DataTable 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public static DataTable ToDataTable<T>(this IEnumerable<T> list)
        {
            using (DataTable dt = new DataTable())
            {
                //创建属性的集合    
                List<PropertyInfo> pList = new List<PropertyInfo>();
                //获得反射的入口    
                Type type = typeof(T);
                //把所有的public属性加入到集合 并添加DataTable的列    
                Array.ForEach<PropertyInfo>(type.GetProperties(), p =>
                {
                    pList.Add(p);
                    Type colType = p.PropertyType;
                    if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition() == typeof(Nullable<>)))
                    {
                        colType = colType.GetGenericArguments()[0];
                    }
                    dt.Columns.Add(p.Name, colType);
                });
                foreach (var item in list)
                {
                    //创建一个DataRow实例    
                    DataRow row = dt.NewRow();
                    //给row 赋值    
                    pList.ForEach(p => row[p.Name] = p.GetValue(item, null));
                    //加入到DataTable    
                    dt.Rows.Add(row);
                }
                return dt;
            }
        }
        #endregion

        #region ========DataTable转换为List集合========
        /// <summary>    
        /// DataTable 转换为List 集合    
        /// </summary>    
        /// <typeparam name="TResult">类型</typeparam>    
        /// <param name="dt">DataTable</param>    
        /// <returns></returns>    
        public static List<T> ToList<T>(this DataTable dt) where T : class, new()
        {
            //创建一个属性的列表    
            List<PropertyInfo> prlist = new List<PropertyInfo>();
            //获取TResult的类型实例  反射的入口 
            Type t = typeof(T);
            //获得TResult 的所有的Public 属性 并找出TResult属性和DataTable的列名称相同的属性(PropertyInfo) 并加入到属性列表     
            Array.ForEach<PropertyInfo>(t.GetProperties(), p => { if (dt.Columns.IndexOf(p.Name) != -1) prlist.Add(p); });
            //创建返回的集合
            List<T> oblist = new List<T>();
            foreach (DataRow row in dt.Rows)
            {
                //创建TResult的实例    
                T ob = new T();
                //找到对应的数据  并赋值    
                prlist.ForEach(p => { if (row[p.Name] != DBNull.Value) p.SetValue(ob, row[p.Name], null); });
                //放入到返回的集合中.    
                oblist.Add(ob);
            }
            return oblist;
        }
        #endregion

        #region ========设置文本框只读========
        /// <summary>
        /// 设置文本框只读
        /// </summary>
        /// <param name="txt"></param>
        public static void ToReadOnly(params HtmlInputText[] txts)
        {
            foreach (HtmlInputText txt in txts)
            {
                txt.ToReadOnly();
            }
        }
        /// <summary>
        /// 设置文本框只读
        /// </summary>
        /// <param name="txt"></param>
        public static void ToReadOnly(this HtmlInputText txt)
        {
            txt.Attributes.Add("ReadOnly", "ReadOnly");
        }
        /// <summary>
        /// 设置文本框只读
        /// </summary>
        /// <param name="txt"></param>
        public static void ToReadOnly(params TextBox[] txts)
        {
            foreach (TextBox txt in txts)
            {
                txt.ToReadOnly();
            }
        }
        /// <summary>
        /// 设置文本框只读
        /// </summary>
        /// <param name="txt"></param>
        public static void ToReadOnly(this TextBox txt)
        {
            txt.Attributes.Add("ReadOnly", "ReadOnly");
        }
        #endregion

        #region Convert
        /// <summary>
        /// 将已经为在URL中传输而编码的字符串转换为解码的字符串。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToUrlDecode(this string value)
        {
            return System.Web.HttpUtility.UrlDecode(value);
        }
        /// <summary>
        /// 对 URL 字符串进行编码。
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToUrlEncode(this string value)
        {
            return System.Web.HttpUtility.UrlEncode(value);
        }
        /// <summary>
        /// 获取string
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToSafeString(this object value)
        {
            if (value == null)
            {
                return string.Empty;
            }
            return value.ToString();
        }
        /// <summary>
        /// 获取string
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToSafeString(this string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return string.Empty;
            }
            return value.ToString(); 
        } 
        /// <summary>
        /// 获得安全字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static int ToSafeInt(this object value)
        {
            if (value == null)
            {
                return 0;
            }
            return ToSafeInt(value.ToSafeString());
        }
        /// <summary>
        /// 获得安全小数
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static decimal ToSafeDecimal(this object value)
        {
            if (value == null)
            {
                return 0.0m;
            }
            return ToSafeDecimal(value.ToSafeString());
        }
        /// <summary>
        /// 获得安全小数
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static decimal ToSafeDecimal(this decimal? value)
        {
            return value.HasValue ? value.Value : 0.0m;
        }
        /// <summary>
        /// 获得安全小数
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static decimal ToSafeDecimal(this string value)
        {
            decimal rtn = 0.0m;
            if (value.IsNullOrEmpty())
            {
                return rtn;
            }
            decimal.TryParse(value, out rtn);
            return rtn;
        }
        /// <summary>
        /// 获得安全Bool
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool ToSafeBool(this bool? value)
        {
            return value.HasValue ? value.Value : false;
        }
        /// <summary>
        /// 获得安全整型数字
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static int ToSafeInt(this int? value)
        {
            return value.HasValue ? value.Value : 0;
        }
        /// <summary>
        /// 获得安全整型数字
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static int ToSafeInt(this string value)
        {
            int rtn = 0;

            if (value.IsNullOrEmpty())
            {
                return rtn;
            }
            int.TryParse(value, out rtn);
            return rtn;
        }
        /// <summary>
        /// 获得安全整型数字
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static long ToSafeLong(this long? value)
        {
            return value.HasValue ? value.Value : 0;
        }
        /// <summary>
        /// 获得安全整型数字
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static long ToSafeLong(this string value)
        {
            long rtn = 0;

            if (value.IsNullOrEmpty())
            {
                return rtn;
            }
            long.TryParse(value, out rtn);
            return rtn;
        }
        /// <summary>
        /// 是否是日期格式
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsDateTime(this string value)
        {
            DateTime rtn = DateTime.MinValue;
            return DateTime.TryParse(value, out rtn);
        }
        /// <summary>
        /// 获得安全日期
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DateTime ToSafeDateTime(this string value)
        {
            DateTime rtn = DateTime.MinValue;
            if (value.IsNullOrEmpty())
            {
                return rtn;
            }
            DateTime.TryParse(value, out rtn);
            return rtn;
        }
        /// <summary>
        /// 获得安全日期
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DateTime ToSafeDateTime(this DateTime? value)
        {
            return value.HasValue ? value.Value : DateTime.MinValue;
        }
        /// <summary>
        /// 转换为整数字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToIntString(this decimal value)
        {
            return value.ToString("0");
        }
        /// <summary>
        /// 转换为整数字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToIntString(this int value)
        {
            return value.ToString("0");
        }
        /// <summary>
        /// 转换为整数字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToDecimalString(this decimal value)
        {
            return value.ToString("0.00");
        }
        /// <summary>
        /// 时间转换为日期字符串
        /// </summary> 
        /// <param name="value"></param>
        /// <returns></returns>
        public static string DateTimeToyyyyMMdd(this DateTime value)
        {
            if (value == DateTime.MinValue)
            {
                return string.Empty;
            }

            return value.ToString("yyyyMMdd");
        }
        /// <summary>
        /// 时间转换为日期字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string DateTimeToyyyy_MM_dd_HH_mm(this DateTime value)
        {
            if (value == DateTime.MinValue)
            {
                return string.Empty;
            }

            return value.ToString("yyyy-MM-dd HH:mm");
        }
        /// <summary>
        /// 时间转换为日期字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string DateTimeToyyyy_MM_dd(this DateTime value)
        {
            if (value == DateTime.MinValue)
            {
                return string.Empty;
            }

            return value.ToString("yyyy-MM-dd");
        }
        /// <summary>
        /// 时间转换为时间字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string DateTimeToyyyyMMddHHmmss(this DateTime value)
        {
            if (value == DateTime.MinValue)
            {
                return string.Empty;
            }

            return value.ToString("yyyyMMddHHmmss");
        }


        public static string DateTimeToyyyy_MM_dd_HH_mm_ss_ms(this DateTime value)
        {
            if (value == DateTime.MinValue)
            {
                return string.Empty;
            }

            return value.ToString("yyyy-MM-dd HH:mm:ss:ms");
        }

        /// <summary>
        /// 时间转换为时间字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string DateTimeToyyyy_MM_dd_HH_mm_ss(this DateTime value)
        {
            if (value == DateTime.MinValue)
            {
                return string.Empty;
            }

            return value.ToString("yyyy-MM-dd HH:mm:ss");
        }
        /// <summary>
        /// 时间转换为时间字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string DateTimeToyyyy_MM_dd_HH_mm_ss(this DateTime? value)
        {
            return value.ToSafeDateTime().ToString("yyyy-MM-dd HH:mm:ss");
        }
        /// <summary>
        /// 时间转换为时间字符串
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string DateTimeToyyyy_MM_dd(this DateTime? value)
        {
            return value.ToSafeDateTime().ToString("yyyy-MM-dd");
        }
        /// <summary>
        /// 日期字符串转换为日期
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DateTime yyyyMMddToDate(this string value)
        {
            // 特殊判断
            if (value == "00000000")
            {
                return DateTime.MinValue;
            }
            else if (value == "99999999")
            {
                return DateTime.MaxValue;
            }

            return DateTime.ParseExact(value, "yyyyMMdd", null);
        }
        /// <summary>
        /// 时间字符串转换为时间
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static DateTime yyyyMMddHHmmssToDate(this string value)
        {
            return DateTime.ParseExact(value, "yyyyMMddHHmmss", null);
        }
        /// <summary>
        /// 布尔字符串转换为布尔
        /// </summary>
        /// <param name="value">字符串</param>
        /// <returns></returns>
        public static bool ToSafeBool(this string value)
        {
            bool rtn = false;
            if (value.IsNullOrEmpty())
            {
                return rtn;
            }
            bool.TryParse(value, out rtn);
            return rtn;
        }
        /// <summary>
        /// 判断字符串是否相等,忽略大小写
        /// </summary>
        /// <param name="value">输入的字符串</param>
        /// <param name="strInValue">被检查的字符串</param>
        /// <returns></returns>
        public static bool ToEquals(this string value, string strInValue)
        {
            return string.Equals(value, strInValue, StringComparison.CurrentCultureIgnoreCase);
        }
        /// <summary>
        /// 字符串替换
        /// </summary>
        /// <param name="value"></param>
        /// <param name="strOld"></param>
        /// <param name="strNew"></param>
        /// <returns></returns>
        public static string ToReplace(this string value, string strOld = "", string strNew = "")
        {
            if (value == null || value.IsNullOrEmpty())
            {
                return string.Empty;
            }
            if (strOld == "")
            {
                return value.ToReplace("'", "").Replace("\r\n", "");
            }
            return value.Replace(strOld, strNew);
        }

        /// <summary>
        /// 将DataTable转换成Json
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToJson(this DataTable dt)
        {
            return JsonHelper.DataTableToJson(dt);
        }

        /// <summary>
        /// 将Json数据转换成DataTable
        /// </summary>
        /// <param name="strJson"></param>
        /// <returns></returns>
        public static DataTable ToDataTable(this string strJson)
        {
            return JsonHelper.ToDataTable(strJson);
        }

        /// <summary>
        /// 将List转换成Json
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToJson<T>(this T list)
        {
            return JsonHelper.JsonSerializer<T>(list);
        }

        /// <summary>
        /// 将Json数据转换成List
        /// </summary>
        /// <param name="strJson"></param>
        /// <returns></returns>
        public static T ToList<T>(this string strJson)
        {
            return JsonHelper.JsonDeserialize<T>(strJson);
        }
        #endregion

        #region IsNullOrEmpty
        /// <summary>
        /// 字符串是否为空或null
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsNullOrEmpty(this string value)
        {
            return string.IsNullOrEmpty(value);
        }
        #endregion

        #region 去除Sql注入
        /// <summary>
        /// 扩展方法，去除SQL注入字符串
        /// </summary>
        /// <param name="value">字符串</param>
        /// <returns>去除SQL注入字符串</returns>
        public static string RemoveSqlInjection(this string value)
        {
            if (value == null)
            {
                return string.Empty;
            }

            return value.Replace("'", "''");
        }
        #endregion

        public static string ToEntityXml(this Entity model)
        {
            var strXml = new StringBuilder();
            strXml.AppendLine("<MonitorData>");
            if (model != null)
            {
                strXml.AppendLine("<rows>");
                Type t = model.GetType();//获得该类的Type
                //再用Type.GetProperties获得PropertyInfo[],然后就可以用foreach 遍历了
                foreach (PropertyInfo pi in t.GetProperties())
                {
                    object value = pi.GetValue(model, null);//用pi.GetValue获得值
                    string name = pi.Name;//获得属性的名字,后面就可以根据名字判断来进行些自己想要的操作
                    strXml.AppendLine("<" + name + ">" + (value ?? "null").ToString() + "</" + name + ">");
                }
                strXml.AppendLine("</rows>");
            }
            strXml.AppendLine("</MonitorData>");
            return strXml.ToString();
        }


        public static string ToLeft(this string value, int left)
        {
            if (string.IsNullOrEmpty(value))
            {
                return string.Empty;
            }
            if (value.Length > left)
            {
                return value.Substring(0, left) + "...";
            }
            return value;
        }

        #region 生成0-9随机数
        /// <summary>
        /// 生成0至9的随机数
        /// </summary>
        /// <param name="VcodeNum">生成长度</param>
        /// <param name="IsWirteCook">是否写入Session</param>
        /// <returns></returns>
        public static string RndNum(int VcodeNum)
        {
            Random rnd = new Random();
            StringBuilder sb = new StringBuilder(VcodeNum);
            int i = 1;
            while (i <= VcodeNum)
            {
                sb.Append(rnd.Next(9).ToString());
                i++;
            }
            return sb.ToString();
        }
        #endregion

        /// <summary>
        /// 写Cookie值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="strCookieName">Cookie名称</param>
        /// <param name="strCookieValue">Cookie值</param>
        public static void WriteCookie(HttpContext context, string strCookieName, string strCookieValue)
        {
            HttpCookie cookie = new HttpCookie("SystemCookie");
            cookie.Values[strCookieName] = strCookieValue;
            cookie.Expires = DateTime.MaxValue;
            context.Response.Cookies.Add(cookie);
        }
        /// <summary>
        /// 获取Cookie值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="strCookieName">Cookie名称</param>
        /// <returns></returns>
        public static string GetCookieValue(HttpContext context, string strCookieName)
        {
            HttpCookie cookie = context.Request.Cookies["SystemCookie"];
            if (cookie != null)
            {
                return cookie[strCookieName];
            }
            return string.Empty;
        }

        #region 生产图片
        /// <summary>
        /// 生产图片
        /// </summary>
        /// <param name="context"></param>
        public static void GenImg(HttpContext context, string checkCode)
        {
            using (Bitmap image = new Bitmap((int)Math.Ceiling((checkCode.Length * 12.5)), 23))
            {
                using (Graphics g = Graphics.FromImage(image))
                {
                    using (MemoryStream ms = new MemoryStream())
                    {
                        g.Clear(Color.White);
                        using (Font font = new Font("Arial", 14, (FontStyle.Italic)))
                        {
                            using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Black, Color.Black, 1.2f, true))
                            {
                                g.DrawString(checkCode, font, brush, 1, 1);
                                image.Save(ms, ImageFormat.Gif);
                                brush.Dispose();
                            }
                            font.Dispose();
                        }
                        context.Response.BinaryWrite(ms.ToArray());
                        ms.Dispose();
                    }
                    g.Dispose();
                }
                image.Dispose();
            }
            context.Response.End();
        }
        #endregion


        private const string strKey = "Password";


        #region ========加密========
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static string ToSafeEncrypt(this string Text)
        {
            return Encrypt(Text);
        }
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static string Encrypt(string Text)
        {
            return Encrypt(Text, strKey);
        }
        /// <summary> 
        /// 加密数据 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        private static string Encrypt(string Text, string sKey)
        {
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                try
                {

                    byte[] inputByteArray;
                    inputByteArray = Encoding.Default.GetBytes(Text);
                    des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
                    des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
                    CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Dispose();
                    StringBuilder ret = new StringBuilder();
                    foreach (byte b in ms.ToArray())
                    {
                        ret.AppendFormat("{0:X2}", b);
                    }
                    return ret.ToString();
                }
                finally
                {
                    ms.Dispose();
                    des.Clear();
                }
            }
        }
        #endregion

        #region ========解密========
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static string ToSafeDecrypt(this string Text)
        {
            return Decrypt(Text);
        }
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="Text"></param>
        /// <returns></returns>
        public static string Decrypt(string Text)
        {
            return Decrypt(Text, strKey);
        }
        /// <summary> 
        /// 解密数据 
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        public static string Decrypt(string Text, string sKey)
        {
            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                try
                {
                    int len;
                    len = Text.Length / 2;
                    byte[] inputByteArray = new byte[len];
                    int x, i;
                    for (x = 0; x < len; x++)
                    {
                        i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                        inputByteArray[x] = (byte)i;
                    }
                    des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
                    des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
                    CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Dispose();
                    return Encoding.Default.GetString(ms.ToArray());
                }
                finally
                {
                    des.Clear();
                    ms.Dispose();
                }
            }
        }
        #endregion
    }
}
